package com.passioneffect.widgets {
	import flash.display.DisplayObject;
	import flash.display.Graphics;
	import flash.display.Sprite;
	import flash.events.Event;

	import com.passioneffect.contentmcs.AbstractPreloader;

	import Number;		

	/**
	 * @author Passion Effect
	 */
	public class CirclePreloader extends AbstractPreloader {

		private var num : Number = 50;
		private var cx : Number = 0;
		private var cy : Number = 0;
		private var angle : Number;
		private var radians : Number;

		private var _radius : Number = 20;
		private var _color : Number = 0x000000;
		private var _stroke : Number = 5;
		private var _speed : Number = 0.02;
		private var _minAlpha : Number = 0;
		private var _maxAlpha : Number = 1;
		private var inited : Boolean;

		[Inspectable(type=Number,defaultValue="0.02")]
		public var fadeSpeed : Number = 0.02;

		
		public function CirclePreloader() {
			if(stage) {
				this.addEventListener(Event.ENTER_FRAME, init);
			}
			stop();
		}

		
		public function init(evt : Event = null) : void {
			this.removeEventListener(Event.ENTER_FRAME, init);
			angle = num / 180;
			radians = (360 / num) * Math.PI / 180;
			if(numChildren > 0)removeChildAt(0);
			inited = true;
			if(autoStart) {
				startMotion();
			}
		}

		public function startMotion() : void {
			if(inited) {
				this.alpha = 0;
				invalidate();
				this.removeEventListener(Event.ENTER_FRAME, fadeOut);
				this.addEventListener(Event.ENTER_FRAME, fadeIn);
			}else {
				autoStart = true;
			}
		}

		public function endMotion() : void {
			this.removeEventListener(Event.ENTER_FRAME, fadeIn);
			this.addEventListener(Event.ENTER_FRAME, fadeOut);
		}

		private function fadeIn(event : Event) : void {
			if(this.alpha >= 1) {
				this.removeEventListener(Event.ENTER_FRAME, fadeIn);
			}
			this.alpha += fadeSpeed;
		}

		private function fadeOut(evt : Event) : void {
			if(this.alpha <= 0) {
				this.removeEventListener(Event.ENTER_FRAME, fadeOut);
			}
			this.alpha -= fadeSpeed;
		}

		private var autoStart : Boolean;

		private function draw(evt : Event = null) : void {
			this.removeEventListener(Event.ENTER_FRAME, draw);
			this.removeEventListener(Event.ENTER_FRAME, preloadMotion);
			while(numChildren > 0) {
				removeChildAt(0);
			}
			
			drawCircles();
			this.addEventListener(Event.ENTER_FRAME, preloadMotion);
		}

		override public function onStart(w : Number,h : Number) : void {
			this.x=w/2;
			this.y=h/2;
			
			autoStart=true;
			init();
		}
		
		override public function onComplete() : void {
			endMotion();
			if(this.parent){
				parent.removeChild(this);
			}
		}

		private function preloadMotion(evt : Event) : void {
			var num : int = numChildren;
			var c : DisplayObject;
			for(var i : int = 0;i < num;i++) {
				c = getChildAt(i);
				if(c.alpha <= minAlpha) {
					c.alpha = maxAlpha;
				}else {
					c.alpha -= speed;
				}
			}
		}

		private function drawCircles() : void {
			var tx : Number;
			var ty : Number;
			var g : Graphics;
			var c : Sprite;
			
			for(var i : int = 0;i < num;i++) {
				tx = cx + Math.sin(radians * i) * radius;
				ty = cy + Math.cos(radians * i) * radius;
				
				c = new Sprite();
				g = c.graphics;
				g.lineStyle(0, 0x000000, 0);
				g.beginFill(color, 1);
				g.drawCircle(0, 0, stroke);
				g.endFill();
				
				c.x = tx;
				c.y = ty;
				c.alpha = i / num * maxAlpha;
				addChild(c);
			}
		}

		private function invalidate() : void {
			if(!inited)return;
			this.addEventListener(Event.ENTER_FRAME, draw);
		}

		[Inspectable(type=Color,defaultValue="#000000")]

		public function get color() : Number {
			return _color;
		}

		public function set color(color : Number) : void {
			_color = color;
			invalidate();
		}

		[Inspectable(type=Number,defaultValue="5")]

		public function get stroke() : Number {
			return _stroke;
		}

		
		public function set stroke(stroke : Number) : void {
			_stroke = stroke;
			invalidate();
		}

		[Inspectable(type=Number,defaultValue="0.02")]

		public function get speed() : Number {
			return _speed;
		}

		public function set speed(speed : Number) : void {
			_speed = speed;
			invalidate();
		}

		[Inspectable(type=Number,defaultValue="0")]

		public function get minAlpha() : Number {
			return _minAlpha;
		}

		public function set minAlpha(minAlpha : Number) : void {
			_minAlpha = minAlpha;
			invalidate();
		}

		[Inspectable(type=Number,defaultValue="1")]

		public function get maxAlpha() : Number {
			return _maxAlpha;
		}

		public function set maxAlpha(maxAlpha : Number) : void {
			_maxAlpha = maxAlpha;
			invalidate();
		}

		[Inspectable(type=Number,defaultValue="20")]

		public function get radius() : Number {
			return _radius;
		}

		public function set radius(radius : Number) : void {
			_radius = radius;
			invalidate();
		}
	}
}
